import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;

public class Server2 {
    public static void main(String[] args) {
        String mode = "AES";
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try{
            serverForClient = new ServerSocket(2010);
        }catch (IOException e1){
            System.out.println(e1);
        }
        String result;
        try{
            System.out.println("等待客户呼叫：");
            socketOnServer = serverForClient.accept();
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());

            //接收加密后的后缀表达式
            String cformula = in.readUTF();
            byte cipher[] = AtoB.parseHexStr2Byte(cformula);


            //接收Client端公钥
            String push = in.readUTF();
            byte np[] = AtoB.parseHexStr2Byte(push);

            //生成服务器共、私钥
            DH.createPubAndPriKey("Serverpub.txt","Serverpri.txt");

            //将服务器公钥传给Client端
            FileInputStream fp = new FileInputStream("Serverpub.txt");
            ObjectInputStream bp = new ObjectInputStream(fp);
            Key kp = (Key) bp.readObject();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(kp);
            byte[] kb = baos.toByteArray();
            String pop = BtoA.parseByte2HexStr(kb);
            out.writeUTF(pop);
            Thread.sleep(1000);

            //生成共享信息，并生成AES密钥
            SecretKeySpec key = Agree.createKey("Serverpub.txt","Clientpri.txt");

            String k = in.readUTF();//读取加密后密钥
            byte[] encryptKey = AtoB.parseHexStr2Byte(k);

            //对加密后密钥进行解密
            Cipher cp = Cipher.getInstance(mode);
            cp.init(Cipher.DECRYPT_MODE,key);
            byte decryptKey [] = cp.doFinal(encryptKey);

            //对密文进行解密
            SecretKeySpec plainkey=new  SecretKeySpec(decryptKey,mode);
            cp.init(Cipher.DECRYPT_MODE, plainkey);
            byte []plain=cp.doFinal(cipher);

            //计算后缀表达式结果
            String formula = new String(plain);
            try{
                Float s1 = MyDC.calrp(formula);
                result = s1.toString();
                //后缀表达式formula调用MyDC进行求值
            }catch (Exception e){
                result = e.getMessage();
            }
            //将计算结果传给Client端
            out.writeUTF(result);
        }catch (Exception e){
            System.out.println("客户已断开"+e);
        }
    }
}
